{include "INC_header.html" title="统一授权登陆页"}
<div class="sso-outlet" id="app-outlet">
    <div class="sso-header">
        <div class="sso-container ui flex-item text-large">
            <div class="start">
                <i class="fa fa-fingerprint"></i>
            </div>
            <div class="center">统一授权</div>
        </div>
        <div class="sso-container ui flex-item">
            <div class="center sso-ad justify-center">
                <div class="text-maximum">统一授权登陆</div>
                <div class="padding-top text-large">支持多系统关联，方便易用！</div>
            </div>
            <div class="end">
                <div class="sso-form">
                    <div class="sso-form-scroller" :class="{ verify:verify  }" v-if="!isLogin">
                        <div class="sso-form-main">
                            <!-- 选项 -->
                            <div class="ui radio-buttons small margin-bottom padding-bottom">
                                <div class="radio-button" :class="{ checked:passwordType=='password' }" @click="passwordType = 'password'; action = '';">密码登陆</div>
                                <div class="radio-button" :class="{ checked:passwordType=='sms' }" @click="passwordType = 'sms'; action = '';">短信验证</div>
                            </div>
                            <!-- 未登陆 -->
                            <div class="text-center padding-top">
                                <div class="sso-avatar"><i class="fa fa-user text-bigger"></i></div>
                            </div>
                            <div class="text-center padding">会员登陆</div>
                            <div class="ui input radius margin-top">
                                <div class="prefix-icon"><i class="fa-solid fa-mobile-screen-button"></i></div>
                                <div class="justify-center padding-right-half" v-if="countryList.length > 1">
                                    <select v-model="countryCode">
                                        <option v-for="cc in countryList" :value="cc.code" :selected="cc.code == countryCode">+{{ cc.code }}</option>
                                    </select>
                                </div>
                                <input type="text" v-model="account" maxlength="30" placeholder="手机号码/用户名">
                            </div>
                            <div class="padding"></div>
                            <div class="ui input radius">
                                <div class="prefix-icon">
                                    <i :class="'fa ' + (passwordType === 'password' ? 'fa-key' : 'fa-code')"></i>
                                </div>
                                <input v-model="password" :type="passwordType === 'password' ? 'password' : 'number'" :maxlength="passwordType === 'password' ? 16 : 6" :placeholder="passwordType === 'password' ? '登陆密码' : '6位数字验证码'">
                                <div class="justify-center" v-if="passwordType !== 'password'">
                                    <div class="ui button clear" @click="showVCode('sms')">{{ smsLockTime > 0 ? smsLockTime : '发送验证码' }}</div>
                                </div>
                            </div>
                            <div class="padding"></div>
                            <div class="ui button block" :class="{ loading:loginLoading  }" @click="login()">登陆</div>
                            <div class="padding"></div>
                            <template v-if="thirdPartyList.length > 0">
                                <div class="padding-top" style="width: 50%; margin: 0 auto;">
                                    <div class="ui divider"><span class="text-small">第三方登陆</span></div>
                                </div>
                                <div class="text-center padding-top">
                                    <a class="ui button small circle margin-half" v-for="tp in thirdPartyList" :href="'{url url='/sso/web/auth'}?plugin=' + tp.plugin + '&clientName=' + clientName">
                                        <i :class="tp.icon"></i>
                                    </a>
                                </div>
                            </template>
                        </div>
                        <!-- 图形验证码 -->
                        <div class="sso-verify-code">
                            <div class="">
                                <div class="ui button circle" @click="verify = false">
                                    <i class="fa fa-close"></i>
                                </div>
                            </div>
                            <div class="v-code-main">
                                <div class="v-code-image">
                                    <img @click="setVCodeSrc" :src="vCodeSrc">
                                </div>
                                <div class="ui input margin-top">
                                    <div class="prefix-icon"><i class="fa fa-code"></i></div>
                                    <input v-model="vCode" type="text" maxlength="4" placeholder="填写上方图形验证码">
                                </div>
                                <div class="padding-top">
                                    <div class="ui button block" :class="{ loading:vCodeLoading  }" @click="checkVCode()">确定</div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="sso-form-main" v-else style="height: 350px; padding: 30px;">
                        <div class="text-center">
                            <a-avatar v-if="user.face != null" :size="58" :src="user.face"></a-avatar>
                            <div class="sso-avatar" v-else><i class="fa fa-user text-bigger"></i></div>
                        </div>
                        <div class="text-center padding-top">{{ user.nickname || user.phone || user.username}}</div>
                        <div class="text-center padding-bottom" v-if="user.admin == 1"><a-tag style="margin: 0;" color="orange">管理员</a-tag></div>
                        <div class="ui flex-item margin">
                            <div class="center">用户名</div>
                            <div class="end">{{ user.username || '未设置' }}</div>
                        </div>
                        <div class="ui flex-item margin">
                            <div class="center">手机号码</div>
                            <div class="end">{{ user.phone || '未设置' }}</div>
                        </div>
                        <div class="ui flex-item margin">
                            <div class="center">昵称</div>
                            <div class="end">{{ user.nickname || '未设置' }}</div>
                        </div>
                        <div class="ui row">
                            <div class="col auto-width" v-if="user.admin == 1"><a class="ui button margin block" href="{url url='/sso/admin'}">进入后台</a></div>
                            <div class="col auto-width">
                                <a-popconfirm title="确定退出？" ok-text="确定" cancel-text="取消" @confirm="logout"><div class="ui button danger margin block">退出登陆</div></a-popconfirm>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script>
    const UA = navigator.userAgent.toLowerCase();
    const clientName = /micromessage/.test(UA) || /alipayclient/.test(UA) ? "APP_BROWSER" : "WEB";
    function redirect() {
        const dfUrl = "{url url='/sso/admin'}";
        const url = "{$get.redirect|default:''}";
        window.location.href = url.length > 0 ? url : dfUrl;
    }
    const { createApp, defineComponent, ref } = Vue;
    const { message, Empty, Modal } = antd;
    const app = createApp({
        data() {
            return {
                //客户端
                clientName: clientName,
                //表单数据
                countryCode: 86,
                //账号(手机号码)
                account: '',
                //密码/验证码
                password: '',
                //登陆方式(手机号码支持使用验证码登陆)
                passwordType: 'password',
                //
                vCodeSrc: "",
                vCode: '',
                vCodeId: '',
                vCodeLoading: false,
                loginLoading: false,
                verify: false,
                smsLockTime: 0,
                action: '',
                //国家代码
                countryList: [{ code:"86", cn:"中国", en:"China" }],
                //如果已登陆
                isLogin: false,
                user: {
                    uid: 0,
                    username: '',
                    face: '',
                    nickname: '',
                    phone: '',
                    registerTime: '',
                    ip: '',
                    state: 1
                },
                //可用的第三方平台
                thirdPartyList: []
            }
        },
        mounted() {
            this.vCodeId = Math.floor(Math.random() * 1000000);
            //获取可用的国家代码
            let self = this;
            axios.get("{url url='/sso/api/sms/countryList'}").then(({ data }) => {
                if (data.error === 0) {
                    self.countryList = data.data || [{ code:"86", cn:"中国", en:"China" }];
                }
            }).catch(() => {
                message.error("获取国家代码失败");
            });
            //检测登陆情况
            axios.get("{url url='/sso/api/user'}").then(({ data }) => {
                if (data.error === 0) {
                    self.isLogin = true;
                    self.user = data.data;
                    redirect();
                } else {
                    self.isLogin = false;
                }
            }).catch(() => { self.isLogin = false; });
            //获取可用的第三方登陆平台
            axios.get("{url url='/sso/api/auth/thirdPartyList'}").then(({ data }) => {
                if (data.error === 0) {
                    self.thirdPartyList = data.data;
                }
            });
        },
        methods: {
            setVCodeSrc: function () {
                this.vCodeSrc = "{url url='/sso/api/vCode'}?id=" + this.vCodeId + "&m=" + Math.random();
                this.vCode = '';
            },
            showVCode: function (action) {
                {literal}
                let cnPhone = /^1[3|4|5|6|7|8|9][0-9]\d{4,8}$/;
                let otherPhone = /^\d{8,}$/;
                {/literal}
                //首先要验证输入
                if (action === 'sms') {
                    if (this.smsLockTime > 0) { return; }
                    if (this.countryCode == '86' && !cnPhone.test(this.account)) {
                        return message.error("请填写国内正确的11位手机号码");
                    }
                    if (!otherPhone.test(this.account)) {
                        return message.error("请填写正确的手机号码");
                    }
                } else if (this.account.toString().length < 6) {
                    return message.error("账号格式错误，至少6个字符长度");
                }
                this.setVCodeSrc();
                this.action = action;
                this.verify = true;
            },
            checkVCode: function () {
                if (this.vCode.toString().length !== 4) {
                    return message.error("请填写完整的图形验证码");
                }
                if (this.action === 'sms') {
                    this.sendSMS();
                } else {
                    this.login();
                }
            },
            lockSMS: function () {
                this.smsLockTime = this.smsLockTime === 0 ? 61 : this.smsLockTime;
                this.smsLockTime--;
                if(this.smsLockTime > 0) {
                    let self = this;
                    setTimeout(() => {
                        self.lockSMS();
                    }, 1000);
                }
            },
            sendSMS: function () {
                if (this.smsLockTime > 0) { return; }
                let self = this;
                self.vCodeLoading = true;
                axios.post("{url url='/sso/api/sms'}", {
                    countryCode: this.countryCode,
                    phone: this.account,
                    vCode: this.vCode,
                    vCodeId: this.vCodeId,
                    action: "auth"
                }).then(({ data }) => {
                    self.vCodeLoading = false;
                    if (data.error !== 0) {
                        if (data.error === 10 || data.error === 11) {
                            self.showVCode('sms');
                        }
                        message.error(data.message);
                    } else {
                        //倒计时
                        self.password = data.data.code || '';
                        self.verify = false;
                        self.lockSMS();
                    }
                }).catch( (_event) => {
                    console.log(_event);
                    message.error('服务端繁忙');
                    self.vCodeLoading = false;
                });
            },
            login: function () {
                if (this.action === 'sms' && this.password.toString().length !== 6) {
                    return message.error("请填写正确的短信验证码，长度是6位数字");
                }
                if (this.action === 'password' && this.password.toString().length < 6) {
                    return message.error("密码至少是6个字符长度");
                }
                if (this.action === 'password') {
                    this.verify = false;
                }
                let self = this;
                self.loginLoading = true;
                axios.post("{url url='/sso/api/auth'}", {
                    countryCode: this.countryCode,
                    account: this.account,
                    passwordType: this.passwordType,
                    password: this.password,
                    vCode: this.vCode,
                    vCodeId: this.vCodeId
                }).then(({ data }) => {
                    self.loginLoading = false;
                    if (data.error) {
                        if (data.error === 20 || data.error === 21) {
                            self.showVCode('sms');
                        } else if (data.error === 10 || data.error === 11) {
                            self.showVCode('password');
                        } else if(data.error === 7) {
                            this.verify = false;
                        }else{
                            self.setVCodeSrc();
                        }
                        message.error(data.message);

                    } else {
                        //登陆成功
                        message.success("登陆授权成功，跳转页面...");
                        redirect();
                    }
                }).catch( () => {
                    message.error('服务端繁忙');
                    self.loginLoading = false;
                });
            },
            logout: function() {
                this.logoutLoading = true;
                let self = this;
                axios.get("{url url='/sso/api/user/logout'}").then(({ data }) => {
                    self.logoutLoading = false;
                    self.isLogin = false;
                }).catch(() => { message.error("服务端繁忙"); self.logoutLoading = false; })
            }
        }
    }).use(antd);
    const vm = app.mount("#app-outlet");
</script>
{include "INC_footer.html"}